#import <Foundation/Foundation.h>

#import "CommonCGDrawings.h"

#define CGDrawingOnePixelWidth       (1.0f/[UIScreen mainScreen].scale)

void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat locations[] = { 0.0, 1.0 };
    
    NSArray *colors = @[(__bridge id) startColor, (__bridge id) endColor];
    
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
    
    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
    
    CGContextSaveGState(context);
    CGContextAddRect(context, rect);
    CGContextClip(context);
    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
    CGContextRestoreGState(context);
    
    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorSpace);
}

void drawRadiusGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor, CGFloat startRadius, CGFloat endRadius)
{
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat locations[] = { 0.0, 1.0 };
    
    NSArray *colors = @[(__bridge id) startColor, (__bridge id) endColor];
    
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
    
    CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
    
    CGContextSaveGState(context);
    CGContextAddRect(context, rect);
    CGContextClip(context);
    CGContextDrawRadialGradient(context, gradient, startPoint, startRadius, endPoint, endRadius, 0);

    CGContextRestoreGState(context);
    
    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorSpace);
}

void draw1PxHorizontalStroke(CGContextRef context, CGPoint startPt, CGFloat width, CGColorRef color)
{
    CGContextSaveGState(context);
    CGContextSetFillColorWithColor(context, color);
    CGContextSetShouldAntialias(context, NO);
    CGContextFillRect(context, CGRectMake(startPt.x, startPt.y, width, CGDrawingOnePixelWidth));
    CGContextRestoreGState(context);
}

void draw3PxHorizontalStroke(CGContextRef context, CGPoint startPt, CGFloat width, CGColorRef color)
{
    CGContextSaveGState(context);
    CGContextSetFillColorWithColor(context, color);
    CGContextSetShouldAntialias(context, NO);
    CGContextFillRect(context, CGRectMake(startPt.x, startPt.y, width, 1.5f));
    CGContextRestoreGState(context);
}

void draw1PxVerticalStroke(CGContextRef context, CGPoint startPt, CGFloat height, CGColorRef color)
{
    CGContextSaveGState(context);
    CGContextSetFillColorWithColor(context, color);
    CGContextSetShouldAntialias(context, NO);
    CGContextFillRect(context, CGRectMake(startPt.x, startPt.y, CGDrawingOnePixelWidth, height));
    CGContextRestoreGState(context);
}

void draw1PtStroke(CGContextRef context, CGPoint startPoint, CGPoint endPoint, CGColorRef color)
{
    
    CGContextSaveGState(context);
    CGContextSetLineCap(context, kCGLineCapSquare);
    CGContextSetStrokeColorWithColor(context, color);
    CGContextSetLineWidth(context, 1.0);
    CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5);
    CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
    
}

CGRect rectFor1PxStroke(CGRect rect)
{
    return CGRectMake(rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height - 1);
}

void drawGlossAndGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
    drawLinearGradient(context, rect, startColor, endColor);
    
    UIColor * glossColor1 = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.35];
    UIColor * glossColor2 = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.1];
    
    CGRect topHalf = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height/2);
    
    drawLinearGradient(context, topHalf, glossColor1.CGColor, glossColor2.CGColor);
}

CGMutablePathRef createArcPathFromBottomOfRect(CGRect rect, CGFloat arcHeight)
{
    CGRect arcRect = CGRectMake(rect.origin.x, rect.origin.y + rect.size.height - arcHeight, rect.size.width, arcHeight);
    
    CGFloat arcRadius = (arcRect.size.height/2) + (pow(arcRect.size.width, 2) / (8*arcRect.size.height));
    CGPoint arcCenter = CGPointMake(arcRect.origin.x + arcRect.size.width/2, arcRect.origin.y + arcRadius);
    
    CGFloat angle = acos(arcRect.size.width / (2*arcRadius));
    CGFloat startAngle = radians(180) + angle;
    CGFloat endAngle = radians(360) - angle;
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, arcCenter.x, arcCenter.y, arcRadius, startAngle, endAngle, 0);
    CGPathAddLineToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect));
    CGPathAddLineToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGPathAddLineToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect));
    
    return path;
}

void drawProgressCicle(CGContextRef context, CGRect rect, CGColorRef filledColor, CGFloat progress)
{
    CGPoint center;
    center.x = rect.origin.x + rect.size.width / 2.0;
    center.y = rect.origin.y + rect.size.height / 2.0;
    
    CGContextSaveGState(context);
    CGContextSetLineWidth(context ,1.0f);
    CGContextSetShouldAntialias(context, YES);
    CGContextSetStrokeColorWithColor(context, filledColor);
    CGContextSetFillColorWithColor(context, filledColor);
    CGContextMoveToPoint(context, center.x, center.y);
    CGContextAddArc(context, center.x, center.y, rect.size.width / 2.0f, -M_PI_2, M_PI*2*progress - M_PI_2, YES);
    CGContextDrawPath(context, kCGPathFill);
    //    CGContextStrokePath(context);
    //    CGContextFillPath(context);
    CGContextRestoreGState(context);
}